#include "../include/Interface.h"
#include <algorithm>
#include <cstdio>
#include <iomanip>
#include <iterator>
#include <memory.h>
#include <stdlib.h>
int trash, rubbish;
#define GET_ON                                                                 \
  trash = system("stty -icanon");                                              \
  trash = system("stty -echo");
#define GET_OFF                                                                \
  rubbish = system("stty icanon");                                             \
  rubbish = system("stty echo");

void Interface::connect_to_server(Server *s) {
  puts("\e[33m正在连接到服务器...");
  server = s;
  puts("\e[32m成功!\e[0m");
}

inline void print_one_line(char c, int len = 100) {
  std::cout << std::setw(len) << std::setfill(c) << "" << std::setfill(' ')
            << std::endl;
}

int Interface::welcome() {
  std::cout << "\e[32m欢迎光临!\e[36m" << std::endl;
  print_one_line('=');
  printf("\e[0m");
  std::cout << std::setiosflags(std::ios::right) << std::setw(25) << "0.润"
            << std::setw(25) << std::setfill(' ') << "1.用户登录"
            << std::setw(25) << "2.用户注册" << std::setw(25) << "3.管理员登录"
            << std::endl;
  printf("\e[36m");
  print_one_line('=');
  std::cout << "\e[32m输入操作：\e[0m";
  GET_ON
  int i;
  do {
    i = getchar();
  } while (i < '0' || i >= '4');
  GET_OFF
  return i;
}

void Interface::sign_up_fail() {
  printf("\e[31m");
  print_one_line('*', 40);
  puts("登录失败，请检查用户名或密码是否正确！");
  print_one_line('*', 40);
  printf("\e[0m");
}

void Interface::sign_up_success() {
  printf("\e[36m");
  print_one_line('*', 10);
  puts("登录成功！");
  print_one_line('*', 10);
  printf("\e[0m");
}
std::string getch() {
  std::string p;
  GET_ON
  char c;
  while (true) {
    c = getchar();
    if (p.empty() && c == 127) { // 127 is backspace
      continue;
    } else if (c == 127) {
      printf("\b \b");
      p.pop_back();
      continue;
    } else if (c == '\n') {
      break;
    } else {
      p.push_back(c);
      putchar('*');
    }
  }
  GET_OFF
  return p;
}

int Interface::user_sign_in() {
  std::cout << "\e[33m输入用户名：\e[0m";
  std::string name;
  std::cin >> name;
  getchar();
  std::string psw;
  std::cout << "\e[33m输入密码：\e[0m";
  psw = getch();
  puts("");
  return server->user_login(name, psw);
}

int Interface::user_sign_up() {
  std::cout << "\e[33m输入用户名：\e[0m";
  std::string name;
  std::cin >> name;
  getchar();
  std::string psw;
  char p[100] = {0};
enterpsw:
  memset(p, 0, 100 * sizeof(char));
  std::cout << "\e[33m输入密码：\e[0m";
  GET_ON
  int i = 0;
  while (true) {
    p[i] = getchar();
    if (i == 0 && p[i] == 127) { // 127 is backspace
      i = 0;
      p[i] = '\0';
      continue;
    } else if (p[i] == 127) {
      printf("\b \b");
      p[i] = '\0';
      i--;
      p[i] = '\0';
      continue;
    } else if (p[i] == '\n') {
      p[i] = '\0';
      break;
    } else {
      putchar('*');
    }
    i++;
  }
  psw = p;
  puts("");
  GET_OFF
  std::string confirm;
  std::cout << "\e[33m确认密码：\e[0m";
  GET_ON
  memset(p, 0, 100 * sizeof(char));
  i = 0;
  while (true) {
    p[i] = getchar();
    if (i == 0 && p[i] == 127) { // 127 is backspace
      i = 0;
      p[i] = '\0';
      continue;
    } else if (p[i] == 127) {
      printf("\b \b");
      p[i] = '\0';
      i--;
      p[i] = '\0';
      continue;
    } else if (p[i] == '\n') {
      p[i] = '\0';
      break;
    } else {
      putchar('*');
    }
    i++;
  }
  confirm = p;
  puts("");
  GET_OFF
  if (confirm == psw) {
    return server->user_sign_up(name, psw);
  } else {
    puts("\e[31m两次密码不一致！\e[0m");
    goto enterpsw;
  }
}

void Interface::user_logout() { server->user_logout(); }

void Interface::user_view(cart *to_view, bool price) {
  printf("\e[32m");
  cart inventory;
  if (to_view == nullptr)
    inventory = server->view_invent();
  else
    inventory = *to_view;
  bool empty = true;
  if (inventory.goods.empty()) {
    empty = true;
  } else {
    for (const auto &i : inventory.goods) {
      if (i.quantity > 0) {
        empty = false;
        break;
      }
    }
  }
  if (empty) {
    std::cout << "\e[31m什么也找不到啊QAQ\e[0m" << std::endl;
    return;
  }
  print_one_line('*');
  printf("\e[33m");
  std::cout << std::setiosflags(std::ios::left) << std::setw(14) << "ID"
            << std::setw(14) << "名称" << '\t' << std::setw(14) << "品牌"
            << '\t' << std::setw(14) << "价格" << '\t' << std::setw(14)
            << "数量" << std::endl;
  for (int i = 0; i < inventory.len(); i++) {
    if (inventory[i].quantity > 0)
      std::cout << inventory[i] << std::endl;
  }
  std::cout << std::resetiosflags(std::ios::left);
  printf("\e[32m");
  print_one_line('*');
  if (price) {
    printf("当前购买所需价格 :");
    if (server->current_user->money >= server->current_user->user_cart.cost()) {
      printf("\e[32m%lf\n", inventory.cost());
    } else {
      printf("\e[31m%lf\e[32m, 您不足以买下这些商品.\n", inventory.cost());
    }
  }
  printf("\e[0m");
}

void Interface::user_search() {
  std::cout << "\e[32m输入商品名称：\e[0m";
  std::string name;
  std::cin >> name;
  getchar();
  // std::cout << name << std::endl;
  cart inventory = server->user_find(
      name, "", [](std::string target, std::string, const good &g) -> bool {
        return grade(g.name, target) > 0;
      });
  if (inventory.len()) {
    user_view(&inventory);
  } else {
    puts("\e[34m您似乎来到了没有商品存在的荒原\e[0m");
  }
}

void Interface::user_add_cart() {
  puts("输入商品名称，品牌和数量：");
  std::string name, brand;
  int num;
  std::cin >> name >> brand >> num;
  good g(0, name, brand, 0, num, "");
  int error_code;
  if (!(error_code = server->user_add_cart(g))) {
    printf("\e[36m");
    print_one_line('*', 20);
    puts("\e[33m已经加入购物车！\e[36m");
    print_one_line('*', 20);
    puts("\e[33m购物车中有：\e[0m");
    user_view(&(server->current_user->user_cart), true);
  } else if (error_code == 1) {
    puts("\e[31m添加失败，没有这个货物！\e[0m");
    puts("当前库存：");
    user_view();
  } else {
    puts("\e[31m添加失败，您要把该商品买成负数了！\e[0m");
    puts("当前库存：");
    user_view();
  }
  getchar();
}

void Interface::user_pop_cart() {
  puts("\e[33m输入商品名称，品牌及数量，将数字留空以删除全部：\e[0m");
  std::string name, brand;
  int num;
  printf("\e[36m");
  printf("名称：");
  getline(std::cin, name);
  printf("品牌：");
  getline(std::cin, brand);
  printf("数量：");
  printf("\e[0m");
  std::string temp;
  getline(std::cin, temp);
  if (temp.empty()) {
    num = -1;
  } else {
    num = atoi(temp.c_str());
  }
  int code = server->user_del_cart(name, brand, num);
  if (code) {
    if (code == -1) {
      puts("\e[31m您删除得太多了！\e[0m");
    } else if (code == -2) {
      puts("\e[31m您删除了一个不在购物车中的东西！\e[0m");
    } else {
      std::cout << code << std::endl;
    }
    return;
  }
  printf("\e[32m");
  print_one_line('*', 30);
  puts("删除成功!");
  print_one_line('*', 30);
  printf("\e[0m");
  puts("\e[33m当前购物车：\e[0m");
  user_view(&(server->current_user->user_cart));
}

void Interface::user_purchase() {
  double last_money = server->current_user->money;
  if (!server->user_purchase()) {
    puts("\e[31m支付失败! 您没有足够的金钱!\e[0m");
    printf("您持有的金钱数 : %lf \n所需要的金钱数 : \e[31m%lf\e[0m \n",
           server->current_user->money, server->current_user->user_cart.cost());
  } else {
    puts("\e[32m支付成功!\e[0m");
    printf("您花去了\e[32m%lf\e[0m金钱, 还剩\e[32m%lf\e[0m\n",
           last_money - server->current_user->money,
           server->current_user->money);
  }
}

void Interface::feed_me(){
  /*std::ifstream qr("./qrcode.txt");
  std::string tmp;
  while(getline(qr,tmp)){
    std::cout << tmp << std::endl;
  }*/
  system("fim qrcode_");
  puts("\e[32m啊哈, 你已经赞助了作者, 来选择你想要的金钱数吧!\e[0m");
  double a;
  std::cin >> a;
  server->feed_me(a);
  server->write_user();
  printf("\e[32m您已成功充值! 当前金额数 : %lf \e[0m\n", server->current_user->money);
}

void Interface::user_menu() {
  while (true) {
    printf("\e[36m");
    print_one_line('=',110);
    puts("\e[0m1.注销登录 2.查看商品 3.商品搜索 4.添加商品至购物车 "
         "5.删除购物车商品 "
         "6.查看购物车 7.结帐 8.赞助作者\e[36m");
    print_one_line('=',110);
    printf("输入操作：\e[0m");
    int i;
    GET_ON
    do {
      i = getchar();
    } while (i <= '0' || i > '8');
    GET_OFF
    puts("");
    switch (i) {
    case '1':
      user_logout();
      return;
      break;
    case '2':
      user_view();
      break;
    case '3':
      user_search();
      break;
    case '4':
      user_add_cart();
      break;
    case '5':
      user_pop_cart();
      break;
    case '6':
      user_view(&(server->current_user->user_cart), true);
      break;
    case '7':
      user_purchase();
      break;
    case '8':
      feed_me();
    default:
      break;
    }
  }
}

bool Interface::admin_login() {
  std::string name, psw;
  printf("\e[34m请输入用户名: \e[0m");
  std::cin >> name;
  getchar();
  printf("\e[34m请输入密码: \e[0m");
  psw = getch();
  if (server->admin_login(name, psw)) {
    puts("\n\e[32m*********\n登陆成功!\n*********\e[0m");
    return true;
  } else {
    puts("\n\e[31m*********\n登陆失败!请检查输入!\n*********\e[0m");
    return false;
  }
}

void Interface::admin_logout() { server->admin_logout(); }

void Interface::admin_view() {
  auto to_view = server->admin_view(1);
  user_view(&to_view);
}

void Interface::admin_add() {
  printf("\e[33m输入商品名称, 品牌和数量: \e[0m");
  std::string name, brand;
  int num;
  std::cin >> name >> brand >> num;
  good a(-1, name, brand, 0, num, "");
  if (std::find(server->invent.goods.begin(), server->invent.goods.end(), a) ==
      server->invent.goods.end()) {
    puts("\e[33e这个商品是新的, 请决定它的价格:\e[0m");
    std::cin >> a.price;
  }
  server->admin_add_good(a);
  puts("\e[32m成功添加! 当前库存: \e[0m");
  admin_view();
}

void Interface::admin_del() {
  std::string num;
  int index;
  do {
    printf("\e[33m输入商品编号: \e[0m");
    std::cin >> num;
  } while (sscanf(num.c_str(), "F%d", &index) != 1);
  if (!server->admin_del_good(index)) {
    puts("\e[32m成功删除! 当前库存: \e[0m");
    admin_view();
  } else {
    puts("\e[31m删除失败! \e[0m");
  }
}

void Interface::admin_set() {
  int num, price;
  std::string name, brand;
  puts("\e[33m请输入需要修改的商品名称和品牌, 如果留空, "
       "则修改所有符合其它条件的商品.");
  printf("\e[33m名称: \e[0m");
  getline(std::cin, name);
  printf("\e[33m品牌:\e[0m");
  getline(std::cin, brand);
  auto found = server->user_find(
      name, brand,
      [](std::string name, std::string brand, const good &b) -> bool {
        return (b.name == name || name.empty()) &&
               (b.brand == brand || brand.empty());
      });
  user_view(&found);
  for (auto &i : found.goods) {
    puts(" \e[33m输入\e[36m");
    std::cout << '\t' << i << std::endl;
    puts("\e[33m的新属性, 如果留空就不设置\e[0m");
    printf("\e[33m数量: ");
    std::string tmp;
    getline(std::cin, tmp);
    if (tmp.empty()) {
      num = -1;
    } else {
      num = atoi(tmp.c_str());
    }
    printf("\e[33m价格: ");
    getline(std::cin, tmp);
    if (tmp.empty()) {
      price = -1;
    } else {
      price = atoi(tmp.c_str());
    }
    if (num == -1) {
      if (price != -1) {
        server->admin_change_price(price, i.id);
      }
    } else {
      // server->admin_change_quantity(num,i.id);
      if (price != -1) {
        server->admin_change_price(price, i.id);
      }
    }
  }
}

void Interface::admin_list() {
  auto a = server->admin_view(0);
  user_view(&a);
}

void Interface::admin_menu() {
  while (true) {
    printf("\e[36m");
    print_one_line('=');
    puts("\e[0m0.注销登录\t1.查询商品\t2.增加商品\t3.删除商品\t"
         "4.操纵市场\t"
         "5.售货清单\e[36m");
    print_one_line('=');
    printf("输入操作：\e[0m");
    int i;
    GET_ON
    do {
      i = getchar();
    } while (i < '0' || i > '5');
    GET_OFF
    puts("");
    switch (i) {
    case '0':
      admin_logout();
      return;
      break;
    case '1':
      admin_view();
      break;
    case '2':
      admin_add();
      break;
    case '3':
      admin_del();
      break;
    case '4':
      admin_set();
      break;
    case '5':
      admin_list();
      break;
    default:
      break;
    }
  }
}

void Interface::menu() {
  int menu_choice;
begin:
  menu_choice = welcome();
  puts("");
  if (menu_choice == '1') {
    int login_success = user_sign_in();
    if (login_success) {
      sign_up_success();
      user_menu();
      goto begin;
    } else {
      sign_up_fail();
      goto begin;
    }
  } else if (menu_choice == '2') {
    int sign_up_succ = user_sign_up();
    if (sign_up_succ) {
      puts("\e[32m注册成功！已自动帮您登录！\e[0m");
      user_menu();
      goto begin;
    } else {
      puts("\e[31m注册失败！昵称被占用！\e[0m");
      goto begin;
    }
  } else if (menu_choice == '3') {
    if (admin_login()) {
      admin_menu();
      goto begin;
    } else {
      goto begin;
    }
  }
}